package com.syg.boot.util.system;

import com.syg.boot.util.number.NumberMoreUtil;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author syg
 * @date 2021年11月24日19:43:12
 * @version 1.0
 */
public class SystemPropertiesUtil {

    public static Boolean getBoolean(String name) {
        String stringResult = System.getProperty(name);
        // return BooleanMoreUtils.toBooleanObject(stringResult);
        return true;
    }

    public static Boolean getBoolean(String name, Boolean defaultValue) {
        String stringResult = System.getProperty(name);
        // return BooleanMoreUtils.toBooleanObject(stringResult, defaultValue);
        return true;
    }

    public static String getString(String name) {
        return System.getProperty(name);
    }

    public static String getString(String name, String defaultValue) {
        return System.getProperty(name, defaultValue);
    }

    public static Integer getInteger(String name) {
        return Integer.getInteger(name);
    }

    public static Integer getInteger(String name, Integer defaultValue) {
        return Integer.getInteger(name, defaultValue);
    }

    public static Long getLong(String name) {
        return Long.getLong(name);
    }

    public static Long getLong(String name, Long defaultValue) {
        return Long.getLong(name, defaultValue);
    }

    public static Double getDouble(String name) {
        return NumberMoreUtil.toDoubleObject(System.getProperty(name));
    }

    public static Double getDouble(String name, Double defaultValue) {
        Double propertyValue = NumberMoreUtil.toDoubleObject(System.getProperty(name));
        return propertyValue != null ? propertyValue : defaultValue;
    }

    public static String getString(String propertyName, String envName, String defaultValue) {
        checkEnvName(envName);
        String propertyValue = System.getProperty(propertyName);
        if (propertyValue != null) {
            return propertyValue;
        } else {
            propertyValue = System.getenv(envName);
            return propertyValue != null ? propertyValue : defaultValue;
        }
    }

    public static Integer getInteger(String propertyName, String envName, Integer defaultValue) {
        checkEnvName(envName);
        Integer propertyValue = NumberMoreUtil.toIntObject(System.getProperty(propertyName));
        if (propertyValue != null) {
            return propertyValue;
        } else {
            propertyValue = NumberMoreUtil.toIntObject(System.getenv(envName));
            return propertyValue != null ? propertyValue : defaultValue;
        }
    }

    public static Long getLong(String propertyName, String envName, Long defaultValue) {
        checkEnvName(envName);
        Long propertyValue = NumberMoreUtil.toLongObject(System.getProperty(propertyName));
        if (propertyValue != null) {
            return propertyValue;
        } else {
            propertyValue = NumberMoreUtil.toLongObject(System.getenv(envName));
            return propertyValue != null ? propertyValue : defaultValue;
        }
    }

    public static Double getDouble(String propertyName, String envName, Double defaultValue) {
        checkEnvName(envName);
        Double propertyValue = NumberMoreUtil.toDoubleObject(System.getProperty(propertyName));
        if (propertyValue != null) {
            return propertyValue;
        } else {
            propertyValue = NumberMoreUtil.toDoubleObject(System.getenv(envName));
            return propertyValue != null ? propertyValue : defaultValue;
        }
    }

    public static Boolean getBoolean(String propertyName, String envName, Boolean defaultValue) {
        checkEnvName(envName);
        // Boolean propertyValue = BooleanMoreUtils.toBooleanObject(System.getProperty(propertyName), (Boolean)null);
        Boolean propertyValue = true;
        if (propertyValue != null) {
            return propertyValue;
        } else {
            // propertyValue = BooleanMoreUtils.toBooleanObject(System.getenv(envName), (Boolean)null);
            propertyValue = true;
            return propertyValue != null ? propertyValue : defaultValue;
        }
    }

    public static synchronized void registerSystemPropertiesListener(SystemPropertiesUtil.PropertiesListener listener) {
        Properties currentProperties = System.getProperties();
        if (!(currentProperties instanceof SystemPropertiesUtil.ListenableProperties)) {
            SystemPropertiesUtil.ListenableProperties newProperties = new SystemPropertiesUtil.ListenableProperties((Properties)currentProperties);
            System.setProperties(newProperties);
            currentProperties = newProperties;
        }

        ((SystemPropertiesUtil.ListenableProperties)currentProperties).register(listener);
    }

    private static void checkEnvName(String envName) {
        if (envName == null || envName.indexOf(46) != -1) {
            throw new IllegalArgumentException("envName " + envName + " has dot which is not valid");
        }
    }

    abstract static class PropertiesListener implements Serializable {
        private static final long serialVersionUID = 1L;
        private String propertyName;

        PropertiesListener(String propertyName) {
            this.propertyName = propertyName;
        }

        String getPropertyName() {
            return this.propertyName;
        }

        void setPropertyName(String propertyName) {
            this.propertyName = propertyName;
        }

        abstract void onChange(String var1, String var2);
    }

    static class ListenableProperties extends Properties {
        private static final long serialVersionUID = -8282465702074684324L;
        private List<PropertiesListener> listeners = new CopyOnWriteArrayList();

        ListenableProperties(Properties properties) {
            super(properties);
        }

        List<SystemPropertiesUtil.PropertiesListener> getListeners() {
            return this.listeners;
        }

        void setListeners(List<SystemPropertiesUtil.PropertiesListener> listeners) {
            this.listeners = listeners;
        }

        void register(SystemPropertiesUtil.PropertiesListener listener) {
            this.listeners.add(listener);
        }

        @Override
        public synchronized Object setProperty(String key, String value) {
            Object result = this.put(key, value);
            Iterator var4 = this.listeners.iterator();

            while(var4.hasNext()) {
                SystemPropertiesUtil.PropertiesListener listener = (SystemPropertiesUtil.PropertiesListener)var4.next();
                if (listener.propertyName.equals(key)) {
                    listener.onChange(key, value);
                }
            }

            return result;
        }
    }
}
